package utils

import (
	"sync"
	"time"
)

type TimeLimitedExecutor struct {
	Task             TaskFunc
	Duration         time.Duration
	LastExecDuration time.Duration
	lock             sync.Mutex
}

func NewTimeLimitedTask(f TaskFunc, d time.Duration) *TimeLimitedExecutor {
	return &TimeLimitedExecutor{
		Task:     f,
		Duration: d,
	}
}

func (t *TimeLimitedExecutor) Run() error {
	if t.Task == nil {
		return ErrActionNil
	}
	ok := t.lock.TryLock()
	if !ok {
		return ErrTaskRunning
	}
	defer t.lock.Unlock()

	// logrus.Info("task start")
	errCh := make(chan (error))
	start := time.Now()
	timer := time.AfterFunc(t.Duration, func() {
		errCh <- ErrActionTimeout
	})
	defer timer.Stop()

	go func() {
		errCh <- t.Task()
	}()
	err := <-errCh
	t.LastExecDuration = time.Since(start)
	// logrus.Info("task end: ", t.LastExecDuration.Milliseconds())
	return err
}
